package com.farm.service.impl;

import com.farm.dao.BookDao;
import com.farm.dao.ProduceDao;
import com.farm.dao.AccountDao;
import com.farm.domain.*;
import com.farm.service.BookService;
import com.farm.utils.MD5Utitl;
import com.farm.utils.Result;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@AllArgsConstructor
public class BookServiceImpl implements BookService {

    DataSourceTransactionManager dataSourceTransactionManager;
    TransactionDefinition transactionDefinition;

    ProduceDao produceDao;
    AccountDao accountDao;
    BookDao bookDao;

    @Override
    public JSONArray getPriceAndCount(Map params) {

        ArrayList list = (ArrayList)  params.get("list");
        JSONArray recordsList= JSONArray.fromObject(list);

        JSONArray finalRecords = new JSONArray();

        double totalPrice = 0;
        for (int i = 0 ; i<recordsList.size();i++) {

            JSONObject record = recordsList.getJSONObject(i);
            int count = record.getInt("count");

            String uuid = record.getString("uuid");
            Produce info = produceDao.getProduceInfo(uuid, "1");
            String merchantID = info.getMerchantID();
            List<ProduceImg> imgs = produceDao.getMerchantProduceImg(uuid);
            Account accountInfo = accountDao.getUserInfoById(merchantID);
            String img = "";
            if (imgs.size()==0){
                img = "/img/produceImg/default.png";
            }else{
                img = imgs.get(0).getImg();
            }

            double price = Double.parseDouble(info.getPrice());
            record.put("produceName",info.getName());
            record.put("name", accountInfo.getName());
            record.put("price",price);
            record.put("img",img);
            record.put("totalPrice",BigDecimal.valueOf(price).multiply(BigDecimal.valueOf(count)).toString());
            totalPrice = totalPrice + ( price * count);
            finalRecords.add(record);
        }
        return finalRecords;
    }

    @Override
    public JSONObject submitBook(String loginName, Map params) {

        JSONObject finalRecord = new JSONObject();
        Account accountInfo = accountDao.getAll(loginName);

        if(accountInfo !=null){
            String id = accountInfo.getId();                                          //用户ID
            String bookID = MD5Utitl.MD5(id + loginName + new Date().getTime());//生成订单编号
            SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            String collectionDate = format.format(new Date());
            finalRecord.put("bookID",bookID);

            String addressID = (String) params.get("addressID");
            ArrayList list = (ArrayList)  params.get("list");
            JSONArray recordsList= JSONArray.fromObject(list);

            List<BookItem> bookItems = new ArrayList<>();

            int totalCount = 0;
            BigDecimal totalPrice = new BigDecimal("0");

            for (int i = 0 ; i<recordsList.size();i++) {

                JSONObject record = recordsList.getJSONObject(i);

                int count = record.getInt("count");
                totalCount = totalCount + count;

                String uuid = record.getString("uuid");
                Produce info = produceDao.getProduceInfo(uuid, "1");
                String merchantID = info.getMerchantID();
                String price = info.getPrice();
                BigDecimal bigDecimalPrice = new BigDecimal(price);
                BigDecimal bigDecimalCount = new BigDecimal(String.valueOf(count));

                BigDecimal multiply = bigDecimalPrice.multiply(bigDecimalCount);
                totalPrice = totalPrice.add(multiply);

                BookItem bookItem = new BookItem();
                bookItem.setBookID(bookID);
                bookItem.setAddressID(addressID);
                bookItem.setMerchantID(merchantID);
                bookItem.setProduceID(uuid);
                bookItem.setProduceName(info.getName());
                bookItem.setProducePrice(price);
                bookItem.setProduceCounts(String.valueOf(count));
                bookItem.setTime(collectionDate);
                bookItems.add(bookItem);
            }

            Book book = new Book();
            book.setBookID(bookID);
            book.setUserID(accountInfo.getId());
            book.setAddressID(addressID);
            book.setTotalCount(String.valueOf(totalCount));
            book.setTotalPrice(String.valueOf(totalPrice.toString()));
            book.setTime(collectionDate);

            TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
            try{
                Integer result = bookDao.addBook(book);
                if (result!=0){
                    log.info("用户生成订单信息成功！");
                    for (BookItem item:bookItems) {
                        bookDao.addBookItem(item);

                        String uuid = item.getProduceID();
                        Produce produceInfo = produceDao.getProduceInfo(uuid, "1");
                        int count = Integer.parseInt(produceInfo.getCount())-Integer.parseInt(item.getProduceCounts());
                        produceInfo.setCount(String.valueOf(count));
                        produceDao.updateProduceDetail(produceInfo);
                    }
                    log.info("用户生成订单明细成功！");
                    dataSourceTransactionManager.commit(transactionStatus);     //手动提交
                }else{
                    return null;
                }
            }catch (Exception e){
                dataSourceTransactionManager.rollback(transactionStatus);       //事务回滚
                return null;
            }
        }else{
            return null;
        }
        return finalRecord;
    }

    @Override
    public Integer cancelBook(Map params) {
        String bookID = (String) params.get("bookID");
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try{
            List<BookItem> boookItems = bookDao.getBookItemByBookId(bookID);
            for (BookItem item:boookItems) {
                String uuid = item.getProduceID();
                Produce produceInfo = produceDao.getProduceInfo(uuid, "1");
                int count = Integer.parseInt(produceInfo.getCount())+Integer.parseInt(item.getProduceCounts());
                produceInfo.setCount(String.valueOf(count));
                produceDao.updateProduceDetail(produceInfo);
            }
            bookDao.cancelBook(bookID);
            bookDao.cancelBookItem(bookID);
        }catch (Exception e){
            log.info("取消失败");
            log.error(e.getMessage());
            dataSourceTransactionManager.rollback(transactionStatus);       //事务回滚
            return 0;
        }
        dataSourceTransactionManager.commit(transactionStatus);     //手动提交
        return 1;
    }

    @Override
    public Result payment(Map params) {
        Result result = new Result();
        String bookID = (String) params.get("bookID");
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            Integer res = bookDao.updateBookStatus(bookID);
            if (res!=0){
                res = bookDao.updateBookItemStatus(bookID);
                if (res!=0){
                    dataSourceTransactionManager.commit(transactionStatus);     //手动提交
                    log.info("用户付款成功！");
                    result.setMsg("付款成功！");
                }else {
                    log.info("用户付款失败！");
                    dataSourceTransactionManager.rollback(transactionStatus);       //事务回滚
                    result.setCode(500);
                    result.setMsg("付款失败！");
                }
            }else {
                log.info("用户付款失败！");
                dataSourceTransactionManager.rollback(transactionStatus);       //事务回滚
                result.setCode(500);
                result.setMsg("付款失败！");
            }

        }catch (Exception e){
            log.info("用户付款失败！");
            log.error(e.getMessage());
            dataSourceTransactionManager.rollback(transactionStatus);       //事务回滚
            result.setCode(500);
            result.setMsg("付款失败！");
        }

        return result;
    }

    @Override
    public List<Book> getBook(String loginName,String status) {
        Account account = accountDao.getAll(loginName);
        if (status==null){
            status="";
        }
        if (account !=null){
            return bookDao.getBook(account.getId(),status);
        }else {
            return null;
        }
    }

    @Override
    public JSONObject getBookItem(Map params) {
        JSONObject finalRecord = new JSONObject();
        String bookID = (String) params.get("bookID");
        Book bookInfo = bookDao.getBookByBookId(bookID);

        Address addressInfo = accountDao.getAddressInfoById(bookInfo.getAddressID());

        List<BookItem> bookItems = bookDao.getBookItemByBookId(bookID);

        JSONArray records = new JSONArray();

        for (BookItem item:bookItems) {
            JSONObject record = new JSONObject();

            String produceID = item.getProduceID();

            List<ProduceImg> imgs = produceDao.getMerchantProduceImg(produceID);
            Account merchantInfo = accountDao.getUserInfoById(item.getMerchantID());
            String merchantName = merchantInfo.getName();
            String img = "";
            if (imgs.size()>0){
                img = imgs.get(0).getImg();
            }else{
                img = "/img/produceImg/default.png";
            }

            record.put("merchantName",merchantName);
            record.put("produceID",produceID);
            record.put("produceName",item.getProduceName());
            record.put("producePrice",item.getProducePrice());
            record.put("produceCounts",item.getProduceCounts());
            record.put("produceTotalPrice",BigDecimal.valueOf(Double.parseDouble(item.getProduceCounts())).multiply(BigDecimal.valueOf(Double.parseDouble(item.getProducePrice()))).toString());
            record.put("produceImg",img);
            record.put("status",item.getStatus());
            records.add(record);
        }
        finalRecord.put("bookBasic",bookInfo);
        finalRecord.put("addressInfo",addressInfo);
        finalRecord.put("bookItemList",records);
        return finalRecord;
    }

    @Override
    public JSONArray getMerchantBook(String loginName) {

        JSONArray records = new JSONArray();
        Account merchantInfo = accountDao.getAll(loginName);
        String id = merchantInfo.getId();
        List<BookItem> bookItems = bookDao.getMerchantBook(id);

        for (BookItem item:bookItems) {
            JSONObject record = new JSONObject();
            Address addressInfo = accountDao.getAddressInfoById(item.getAddressID());
            List<ProduceImg> imgs = produceDao.getMerchantProduceImg(item.getProduceID());
            String img = "";
            if (imgs.size()>0){
                img = imgs.get(0).getImg();
            }else{
                img = "/img/produceImg/default.png";
            }
            record.put("address",addressInfo);
            record.put("img",img);
            record.put("bookID",item.getBookID());
            record.put("produceID",item.getProduceID());
            record.put("produceName",item.getProduceName());
            record.put("producePrice",item.getProducePrice());
            record.put("produceCounts",item.getProduceCounts());
            record.put("produceTotalPrice",BigDecimal.valueOf(Double.parseDouble(item.getProducePrice())).multiply(BigDecimal.valueOf(Double.parseDouble(item.getProduceCounts()))).toString());
            record.put("time",item.getTime());
            records.add(record);
        }
        return records;
    }

    @Override
    public Integer shipment(Map params) {

        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        Integer res = null;
        try{
            String bookID = (String) params.get("bookID");
            String produceID = (String) params.get("produceID");
            res = bookDao.shipment(bookID,produceID);
        }catch (Exception e){
            dataSourceTransactionManager.rollback(transactionStatus);       //事务回滚
            return 0;
        }
        dataSourceTransactionManager.commit(transactionStatus);
        return res;
    }

    @Override
    public JSONArray userShipment(String loginName) {
        JSONArray records = new JSONArray();
        Account accountInfo = accountDao.getAll(loginName);
        List<Book> books = bookDao.getBook(accountInfo.getId(), "");
        for (Book book:books) {
            String bookID = book.getBookID();
            List<BookItem> bookItems = bookDao.getBookItemByBookId(bookID);
            for (BookItem item:bookItems) {
                if (item.getStatus().equals("2")){
                    JSONObject record = new JSONObject();
                    Address addressInfo = accountDao.getAddressInfoById(item.getAddressID());
                    List<ProduceImg> imgs = produceDao.getMerchantProduceImg(item.getProduceID());
                    String img = "";
                    if (imgs.size()>0){
                        img = imgs.get(0).getImg();
                    }else{
                        img = "/img/produceImg/default.png";
                    }
                    record.put("address",addressInfo);
                    record.put("img",img);
                    record.put("bookID",item.getBookID());
                    record.put("produceName",item.getProduceName());
                    record.put("producePrice",item.getProducePrice());
                    record.put("produceCounts",item.getProduceCounts());
                    record.put("produceTotalPrice",BigDecimal.valueOf(Double.parseDouble(item.getProducePrice())).multiply(BigDecimal.valueOf(Double.parseDouble(item.getProduceCounts()))).toString());
                    record.put("time",item.getTime());
                    records.add(record);
                }else{
                    continue;
                }
            }
        }


        return records;
    }

    @Override
    public JSONArray userBookHarvest(String loginName) {
        JSONArray records = new JSONArray();
        Account accountInfo = accountDao.getAll(loginName);
        List<Book> books = bookDao.getBook(accountInfo.getId(), "");
        for (Book book:books) {
            String bookID = book.getBookID();
            List<BookItem> bookItems = bookDao.getBookItemByBookId(bookID);
            for (BookItem item:bookItems) {
                if (item.getStatus().equals("3")){
                    JSONObject record = new JSONObject();
                    Address addressInfo = accountDao.getAddressInfoById(item.getAddressID());
                    List<ProduceImg> imgs = produceDao.getMerchantProduceImg(item.getProduceID());
                    String img = "";
                    if (imgs.size()>0){
                        img = imgs.get(0).getImg();
                    }else{
                        img = "/img/produceImg/default.png";
                    }
                    record.put("address",addressInfo);
                    record.put("img",img);
                    record.put("bookID",item.getBookID());
                    record.put("produceID",item.getProduceID());
                    record.put("produceName",item.getProduceName());
                    record.put("producePrice",item.getProducePrice());
                    record.put("produceCounts",item.getProduceCounts());
                    record.put("produceTotalPrice",BigDecimal.valueOf(Double.parseDouble(item.getProducePrice())).multiply(BigDecimal.valueOf(Double.parseDouble(item.getProduceCounts()))).toString());
                    record.put("time",item.getTime());
                    records.add(record);
                }
            }
        }

        return records;
    }

    @Override
    public Integer userConfirmBookHarvest(Map params) {
        String bookID = (String) params.get("bookID");
        String produceID = (String) params.get("produceID");
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try{
            Integer res = bookDao.userConfirmBookHarvest(bookID,produceID);
            if (res!=0){
                dataSourceTransactionManager.commit(transactionStatus);
                return res;
            }else {
                dataSourceTransactionManager.rollback(transactionStatus);       //事务回滚
                return 0;
            }
        }catch (Exception e){
            log.error(e.getMessage());
            dataSourceTransactionManager.rollback(transactionStatus);       //事务回滚
            return 0;
        }
    }

    @Override
    public JSONArray userFinishBook(String loginName) {
        JSONArray records = new JSONArray();
        Account accountInfo = accountDao.getAll(loginName);
        List<Book> books = bookDao.getBook(accountInfo.getId(), "");
        for (Book book:books) {
            String bookID = book.getBookID();
            List<BookItem> bookItems = bookDao.getBookItemByBookId(bookID);
            for (BookItem item:bookItems) {
                if (item.getStatus().equals("4")){
                    JSONObject record = new JSONObject();
                    Address addressInfo = accountDao.getAddressInfoById(item.getAddressID());
                    List<ProduceImg> imgs = produceDao.getMerchantProduceImg(item.getProduceID());
                    String img = "";
                    if (imgs.size()>0){
                        img = imgs.get(0).getImg();
                    }else{
                        img = "/img/produceImg/default.png";
                    }
                    record.put("address",addressInfo);
                    record.put("img",img);
                    record.put("bookID",item.getBookID());
                    record.put("produceName",item.getProduceName());
                    record.put("producePrice",item.getProducePrice());
                    record.put("produceCounts",item.getProduceCounts());
                    record.put("produceTotalPrice",BigDecimal.valueOf(Double.parseDouble(item.getProducePrice())).multiply(BigDecimal.valueOf(Double.parseDouble(item.getProduceCounts()))).toString());
                    record.put("time",item.getTime());
                    records.add(record);
                }else{
                    continue;
                }
            }
        }

        return records;

    }

    @Override
    public JSONArray userBookStatus(String loginName,String status) {
        JSONArray records = new JSONArray();
        Account accountInfo = accountDao.getAll(loginName);
        List<Book> books = bookDao.getBook(accountInfo.getId(), "");
        for (Book book:books) {
            String bookID = book.getBookID();
            List<BookItem> bookItems = bookDao.getBookItemByBookId(bookID);
            for (BookItem item:bookItems) {
                if (item.getStatus().equals(status)){
                    JSONObject record = new JSONObject();
                    Address addressInfo = accountDao.getAddressInfoById(item.getAddressID());
                    List<ProduceImg> imgs = produceDao.getMerchantProduceImg(item.getProduceID());
                    String img = "";
                    if (imgs.size()>0){
                        img = imgs.get(0).getImg();
                    }else{
                        img = "/img/produceImg/default.png";
                    }
                    record.put("address",addressInfo);
                    record.put("img",img);
                    record.put("bookID",item.getBookID());
                    record.put("produceID",item.getProduceID());
                    record.put("produceName",item.getProduceName());
                    record.put("producePrice",item.getProducePrice());
                    record.put("produceCounts",item.getProduceCounts());
                    record.put("produceTotalPrice",BigDecimal.valueOf(Double.parseDouble(item.getProducePrice())).multiply(BigDecimal.valueOf(Double.parseDouble(item.getProduceCounts()))).toString());
                    record.put("time",item.getTime());
                    records.add(record);
                }
            }
        }
        return records;
    }


}
